package org.springblade.modules.admin.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.Func;
import org.springblade.modules.admin.dto.AbarbeitungPlanDateUpdateDTO;
import org.springblade.modules.admin.dto.PlanAbarbeitungSaveDTO;
import org.springblade.modules.admin.dto.PlanAbarbeitungSearchDTO;
import org.springblade.modules.admin.dto.plan.PlanSearchDTO;
import org.springblade.modules.admin.entity.MaintainAbarbeitungDetail;
import org.springblade.modules.admin.entity.MaintainAbarbeitungRecord;
import org.springblade.modules.admin.entity.MaintainScoreIssue;
import org.springblade.modules.admin.enums.MaintainPlanContentEnum;
import org.springblade.modules.admin.enums.TaskStatusEnum;
import org.springblade.modules.admin.service.MaintainAbarbeitungService;
import org.springblade.modules.admin.service.MaintainScoreIssueService;
import org.springblade.modules.admin.vo.FromPlanVO;
import org.springblade.modules.admin.vo.PlanAbarbeitungDetailVO;
import org.springblade.modules.admin.vo.PlanAbarbeitungPageVO;
import org.springblade.modules.admin.vo.plan.PlanListVo;
import org.springblade.modules.admin.vo.plan.PlanSignStatusVo;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @Date 10:36 2025/4/9
 * @Description {
 * 评分问题
 * }
 * @Author lsay
 **/
@AllArgsConstructor
@RestController
@RequestMapping("/maintain/abarbeitung")
public class MaintainAbarbeitungController {

	private final MaintainAbarbeitungService abarbeitungService;

	/**
	 * @return 工单id
	 * @Author lsay
	 * @Description {
	 * 新增整改工单
	 * }
	 * @Date 10:45 2025/4/9
	 * @Param
	 **/
	@PostMapping("/by/submit")
	public R<Long> submit(@RequestBody PlanAbarbeitungSaveDTO saveDTO) {
		return R.data(abarbeitungService.submit(saveDTO));
	}

	/**
	 * @return 成功与否
	 * @Author lsay
	 * @Description {
	 * 整改工单指派人员
	 * }
	 * @Date 10:45 2025/4/18
	 * @Param
	 **/
	@PostMapping("/add/user")
	public R<Boolean> addUser(@RequestBody PlanAbarbeitungSaveDTO saveDTO) {
		return R.data(abarbeitungService.addUser(saveDTO));
	}

	/**
	 * @return 成功与否
	 * @Author lsay
	 * @Description {
	 * 整改工单分页
	 * }
	 * @Date 16:40 2025/4/10
	 * @Param
	 **/
	@GetMapping("/page")
	public R<IPage<PlanAbarbeitungPageVO>> selectPage(PlanAbarbeitungSearchDTO searchDTO, Query query) {
		return R.data(abarbeitungService.selectPage(searchDTO, Condition.getPage(query)));
	}

	/**
	 * @return 工单各状态统计
	 * @Author lsay
	 * @Description {
	 * 获取整改工单页面状态统计
	 * }
	 * @Date 13:49 2025/4/14
	 * @Param
	 **/
	@GetMapping("/page/count")
	public R<Map<String, Object>> selectPageCount() {
		return R.data(abarbeitungService.selectPageCount());
	}

	/**
	 * @return 整改工单详情
	 * @Author lsay
	 * @Description {
	 * 整改工单详情
	 * }
	 * @Date 13:49 2025/4/14
	 * @Param
	 **/
	@GetMapping("/detail")
	public R<PlanAbarbeitungDetailVO> selectDetail(Long planId) {
		return R.data(abarbeitungService.selectDetail(planId));
	}

	/**
	 * @return 成功与否
	 * @Author lsay
	 * @Description {
	 * 关闭整改任务
	 * }
	 * @Date 15:51 2025/4/14
	 * @Param
	 **/
	@PostMapping("/close")
	public R<Boolean> close(@RequestBody MaintainAbarbeitungRecord record) {
		return R.data(abarbeitungService.close(record));
	}

	/**
	 * @return 成功与否
	 * @Author lsay
	 * @Description {
	 * 转派整改任务
	 * }
	 * @Date 13:47 2025/4/15
	 * @Param
	 **/
	@PostMapping("/redeploy")
	public R<Boolean> redeploy(@RequestBody MaintainAbarbeitungRecord record) {
		return R.data(abarbeitungService.redeploy(record));
	}

	/**
	 * @return 成功与否
	 * @Author lsay
	 * @Description {
	 * 重新打开整改任务
	 * }
	 * @Date 13:47 2025/4/15
	 * @Param
	 **/
	@PostMapping("/reopen")
	public R<Boolean> reopen(@RequestBody MaintainAbarbeitungRecord record) {
		return R.data(abarbeitungService.reopen(record));
	}

	/**
	 * @return 整改工单操作记录列表
	 * @Author lsay
	 * @Description {
	 * 整改工单操作记录列表
	 * }
	 * @Date 9:30 2025/4/17
	 * @Param
	 **/
	@GetMapping("/record/list")
	public R<List<MaintainAbarbeitungRecord>> recordList(Long planId) {
		return R.data(abarbeitungService.recordList(planId));
	}

	/**
	 * @return 整改工单来源工单
	 * @Author lsay
	 * @Description {
	 * 整改工单来源工单
	 * }
	 * @Date 9:30 2025/4/17
	 * @Param
	 **/
	@GetMapping("/from/plan")
	public R<List<FromPlanVO>> fromPlan(Long planId) {
		return R.data(abarbeitungService.fromPlan(planId));
	}

	/**
	 * @return 成功与否
	 * @Author lsay
	 * @Description {
	 * 更新整改任务时间
	 * }
	 * @Date 13:47 2025/4/17
	 * @Param
	 **/
	@PostMapping("/update/date")
	public R<Boolean> updateDate(@RequestBody AbarbeitungPlanDateUpdateDTO dateUpdateDTO) {
		return R.data(abarbeitungService.updateDate(dateUpdateDTO));
	}

	/**
	 * @return 时间结果
	 * @Author lsay
	 * @Description {
	 * 获取电梯下次保养时间
	 * }
	 * @Date 9:28 2025/4/22
	 * @Param
	 **/
	@GetMapping("/next/by/date")
	public R<String> nextByDate(Long planId) {
		return R.data(abarbeitungService.selectNextByDate(planId));
	}

	/**
	 * @return
	 * @Author lsay
	 * @Description {
	 * 执行整改工单逾期状态及转派定时任务
	 * }
	 * @Date 15:34 2025/4/23
	 * @Param
	 **/
	@GetMapping("/task")
	public R<?> task() {
		abarbeitungService.updateZgPlanOverdueType(AuthUtil.getTenantId());
		return R.data(Boolean.TRUE);
	}


	@PostMapping("down/excel")
	@ApiOperation(value = "下载保养工单")
	public void planListDownExcel(HttpServletResponse response, @RequestBody PlanAbarbeitungSearchDTO searchDTO) throws IOException {
		ExcelWriter excelWriter = null;
		ServletOutputStream outputStream = response.getOutputStream();
		List<PlanAbarbeitungPageVO> records = abarbeitungService.downList(searchDTO);
		try {
			List<List<String>> rows = new ArrayList<>();
			List<String> title = CollUtil.newArrayList
				("项目名称", "电梯位置", "任务编号", "创建人", "计划执行人", "计划截止时间", "计划逾期状态", "是否转派", "转派次数", "转派人员", "转派截止时间",
					"转派逾期状态", "参与工单执行人", "实际执行人", "创建时间", "开始时间", "完成时间", "任务耗时", "整改事项", "是否重新打开", "重新打开次数", "紧急程度", "任务状态");
			rows.add(title);
			for (PlanAbarbeitungPageVO planListVo : records) {
				List<String> row = new ArrayList<>(17);
				row.add(Convert.toStr(planListVo.getBuildingName(), ""));
				row.add(Convert.toStr(planListVo.getElevatorAddress(), ""));
				row.add(Convert.toStr(planListVo.getPlanId(), ""));
				row.add(Convert.toStr(planListVo.getCreateUserName(), ""));
				row.add(Convert.toStr(planListVo.getPlanExecutorNames(), ""));
				if (planListVo.getPlanFinishDate() != null) {
					row.add(DateUtil.format(planListVo.getPlanFinishDate(), "yyyy-MM-dd") + " 23:59:59");
				} else {
					row.add("/");
				}
				String overdueTypeName = Convert.toStr(planListVo.getOverdueTypeName(), "").equals("未逾期") ? "正常" : Convert.toStr(planListVo.getOverdueTypeName(), "");
				row.add(overdueTypeName);
				Integer redeployCount = Convert.toInt(planListVo.getRedeployCount(), 0);
				if (redeployCount > 0) {
					row.add("是");
					row.add(redeployCount.toString());
					row.add(planListVo.getRedeployUserNames());
				} else {
					row.add("否");
					row.add("0");
					row.add("/");
				}

				//转派截止时间
				if (planListVo.getRedeployFinishDate() != null) {
					row.add(DateUtil.format(planListVo.getRedeployFinishDate(), "yyyy-MM-dd")  + " 23:59:59");
				} else {
					row.add("/");
				}
				String redeployOverdueTypeName = Convert.toStr(planListVo.getRedeployOverdueStatusName(), "").equals("未逾期") ? "正常" : Convert.toStr(planListVo.getRedeployOverdueStatusName(), "");
				row.add(redeployOverdueTypeName);
				row.add(planListVo.getPlanParticipationNames());
				row.add(planListVo.getPlanFinishUserNames());
				row.add(DateUtil.format(planListVo.getCreateTime(), "yyyy-MM-dd HH:mm:ss"));
				if (planListVo.getPlanBeginTime() != null) {
					row.add(DateUtil.format(planListVo.getPlanBeginTime(), "yyyy-MM-dd HH:mm:ss"));
				} else {
					row.add("/");
				}
				if (planListVo.getPlanEndTime() != null) {
					row.add(DateUtil.format(planListVo.getPlanEndTime(), "yyyy-MM-dd HH:mm:ss"));
				} else {
					row.add("/");
				}
				row.add(Convert.toStr(planListVo.getWorkMinute(),"0"));
				row.add(Convert.toStr(planListVo.getScoreIssue(),"0"));
				row.add(Convert.toInt(planListVo.getReopenCount(),0)>0?"是":"否");
				row.add(Convert.toStr(planListVo.getReopenCount(),"0"));
				row.add(Convert.toStr(planListVo.getEmerProcTypeName(),"/"));
				row.add(Convert.toStr(planListVo.getPlanStatusName(),"/"));
				rows.add(row);
			}
			String fileName = DateUtil.format(new Date(), "yyyyMMddHHmmss") + ".xlsx";
			setResponseHeader(response, fileName);
			excelWriter = ExcelUtil.getBigWriter(rows.size());
			excelWriter.write(rows, true);
			excelWriter.flush(outputStream, true);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (excelWriter != null) {
				excelWriter.close();
			}
			outputStream.close();
		}
	}


	/**
	 * 功能描述: 发送响应流方法
	 */
	private void setResponseHeader(HttpServletResponse response, String fileName) {
		try {
			try {
				fileName = new String(fileName.getBytes(), "ISO8859-1");
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
			response.setContentType("application/octet-stream;charset=ISO8859-1");
			response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
			response.addHeader("Pargam", "no-cache");
			response.addHeader("Cache-Control", "no-cache");
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

}
